package com.starview.platform.data.type;

import java.util.Stack;
import java.util.Map.Entry;

public abstract class AbstractTypeVisitor implements ITypeVisitor
{
  private final Stack<String> exclusions = new Stack<String>();

  @Override
  public void visitSimpleType(Type t)
  {
  }

  @Override
  public void visitTypeVar(TypeVar v)
  {
    IType type = v.getBoundValue();
    if (type != null)
      type.accept(this);
  }

  @Override
  public void visitTypeExp(TypeExp t)
  {
    t.getTypeCon().accept(this);
    for (IType arg : t.getTypeArgs())
      arg.accept(this);
  }

  @Override
  public void visitTypeInterface(TypeInterfaceType t)
  {
    for (Entry<String, IType> entry : t.getAllFields().entrySet())
      entry.getValue().accept(this);
  }

  @Override
  public void visitExistentialType(QuantifiedType t)
  {
    exclusions.push(t.getBoundVar().getVarName());
    t.getBoundType().accept(this);
    exclusions.pop();
  }

  @Override
  public void visitUniversalType(UniversalType t)
  {
    exclusions.push(t.getBoundVar().getVarName());
    t.getBoundType().accept(this);
    exclusions.pop();
  }

  protected boolean isExcluded(String name)
  {
    return exclusions.contains(name);
  }
}
